# -*- coding: utf-8 -*-
import logging

from common import orm
from common.mch import handler as mch_handler
from common.utils import tz
from common.timer import TIMER_EVENT_TYPE, TimerEvent, EventHandler


_LOGGER = logging.getLogger('timer')


def _calc_delay_notify_ts(pay):
    """
    采用退避重发机制 15/15/30/180/1800/1800/1800/1800/3600/3600/...
    最长24小时
    """
    payed_ts = tz.to_ts(pay.payed_at)
    if tz.now_ts() - payed_ts > 24*3600:
        _LOGGER.warn('pay[%s] notify has expired in 24 hours!', pay.id)
        return None
    if pay.notify_count <= 2:
        return 15
    if pay.notify_count == 3:
        return 30
    if pay.notify_count == 4:
        return 180
    if pay.notify_count <= 8:
        return 1800
    return 3600


def submit_notify_event(pay):
    event_msg = {'pay_id': pay.id}
    delay_ts = _calc_delay_notify_ts(pay)
    if not delay_ts:
        return
    expire_ts = tz.now_ts() + delay_ts
    event_id = TimerEvent.submit(
        TIMER_EVENT_TYPE.MCH_NOTIFY, event_msg, expire_ts)
    _LOGGER.info(
        'start timer to notify pay %s event in %s seconds later. event id[%s]',
        pay.id, delay_ts, event_id)


class MchNotifyHandler(EventHandler):

    def process(self, event_msg):
        _LOGGER.info('mch notify Event [%s]' % event_msg)
        try:
            pay_id = event_msg['pay_id']
            # notify
            _LOGGER.info('to process notify_mch, pay[%s]', pay_id)
            pay = order_db.get_pay(pay_id)
            success, pay = mch_handler.notify_mch(pay)
            if not success:
                # start timer to notify again
                submit_notify_event(pay)
            _LOGGER.info('pay notified %s' % event_msg)
        except Exception as e:
            orm.session.rollback()
            _LOGGER.exception('MchNotifyHandler process error.(%s)' % e)
            submit_notify_event(pay)
        finally:
            orm.session.close()
        return True